#include <iostream>
#include <string>
#include <cstdio>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
using namespace std;

const string comm_path = "/home/tsx/linux/24-5-2/myShm/myfifo";
#define Creater 1 // 身份码，1表示创建管道者，2表示使用者
#define User 2
#define Defaultfd -1
#define Read_Mode O_RDONLY
#define Write_Mode O_WRONLY
#define BaseSize 4096 // 默认读管道的数据大小

class NamePipe
{
private:
  void CreatFifo()
  {
    int res = mkfifo(_fifo_path.c_str(), 0777);
    if (res != 0)
    {
      perror("mkfifo");
    }
  }

  bool OpenNameFifo(int mode)
  {
    _fd = open(_fifo_path.c_str(), mode);
    if (_fd < 0)
    {
      cout << _fd << endl;
      return false;
    }

    return true;
  }

public:
  NamePipe(const string &path, int who) // 构造函数，根据身份码来决定谁创建管道
      : _fifo_path(path), _id(who), _fd(Defaultfd)
  {
    if (_id == Creater)
    {
      CreatFifo(); // 创建管道
      cout << "creat a fifo" << endl;
    }
  }

  // 读写操作
  bool OpenForWrite()
  {
    return OpenNameFifo(Write_Mode);
  }

  bool OpenForRead()
  {
    return OpenNameFifo(Read_Mode);
  }

  int ReadNamePipe(string &out)
  { // 向管道中读取数据
    char buffer[BaseSize];
    int n = read(_fd, buffer, sizeof(buffer) - 1);
    if (n > 0)
    {
      buffer[n] = '\0';
      out = buffer;
    }
    return n;
  }

  int WriteNamePipe(string in)
  { // 像管道中写数据
    return write(_fd, in.c_str(), in.size());
  }

  ~NamePipe() // 析构，删除管道文件，关闭文件
  {
    if (_id == Creater)
    {
      int res = unlink(_fifo_path.c_str()); // 删除管道文件
      if (res != 0)
      {
        perror("unlink");
      }
    }
    if (_fd != Defaultfd)
    { // 关闭文件
      close(_fd);
    }
    }
  void Print()
  {
    cout << _fd << " " << _fifo_path << " " << _id << endl;
  }

private:
  int _fd;                 // FIFO描述fu
  const string _fifo_path; // 管道路径
  int _id;                 // 身份码
};